package com.jt.config;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;

@Configuration
public class RedisConfig {

    public RedisSerializer<?> redisSerializer(){
        //1.定义序列化对象,并指定可以对哪些类型对象进行序列化
        Jackson2JsonRedisSerializer serializer=
                new Jackson2JsonRedisSerializer(Object.class);
        //2.构建对象映射对象(将对象转换为json或者将json转换对象)
        ObjectMapper objectMapper=new ObjectMapper();
        //2.1设置序列化时的可见方法
        objectMapper.setVisibility(PropertyAccessor.GETTER,//序列化时只调用get方法
                JsonAutoDetect.Visibility.ANY);//get方法的访问修饰符可以任意
        //2.2序列化时值的规则定义(例如值为null还是否要序列化)
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        //2.3激活类型存储(这个一般在反序列化时有用,否则反序列化时数据默认存储在LinkedHashMap中)
        objectMapper.activateDefaultTyping(
                objectMapper.getPolymorphicTypeValidator(),//开启多态校验
                ObjectMapper.DefaultTyping.NON_FINAL,//序列化的来不能使用final修饰
                JsonTypeInfo.As.PROPERTY);//将类型以属性形式存储到json串中
        //2.4设置对象映射对象
        serializer.setObjectMapper(objectMapper);

        return serializer;
    }

    @Bean
    public RedisTemplate<Object, Object> redisTemplate(
            RedisConnectionFactory connectionFactory) {
        RedisTemplate<Object, Object> redisTemplate =
                new RedisTemplate<>();
        redisTemplate.setConnectionFactory(connectionFactory);
        //设置序列化方式
        redisTemplate.setKeySerializer(RedisSerializer.string());
        redisTemplate.setHashKeySerializer(RedisSerializer.string());
        redisTemplate.setHashValueSerializer(redisSerializer());
        redisTemplate.setValueSerializer(redisSerializer());
        //建议更新了序列化方式后,执行一下如下方法
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }
    /**
     * 基于业务定制RedisTemplate对象
     * @param connectionFactory
     * @return
     */
    @Bean
    public RedisTemplate<Object, Object> simpleRedisTemplate(
            RedisConnectionFactory connectionFactory){
        RedisTemplate<Object, Object> redisTemplate=
                new RedisTemplate<>();
        redisTemplate.setConnectionFactory(connectionFactory);
        //设置序列化方式
        redisTemplate.setKeySerializer(RedisSerializer.string());
        redisTemplate.setHashKeySerializer(RedisSerializer.string());
        redisTemplate.setHashValueSerializer(RedisSerializer.string());
        //redisTemplate.setValueSerializer(RedisSerializer.java());
        redisTemplate.setValueSerializer(RedisSerializer.json());
        return redisTemplate;
    }//参考renren.io源代码
}